package com.zzc.alfred.entity.service.search;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.ansj.lucene4.AnsjAnalysis;
import org.apache.ibatis.datasource.DataSourceFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.zzc.alfred.entity.common.QueyException;
import com.zzc.alfred.entity.common.constant.SourceEnum;
import com.zzc.alfred.entity.util.DateUtil;
import com.zzc.alfred.entity.util.LuceneUtils;
import com.zzc.alfred.entity.web.view.CrawlProductView;
import com.zzc.alfred.entity.web.view.ProductBusinessView;

import jodd.json.JsonParser;
import jodd.util.StringUtil;

public class ProductSearchService {

	private static Directory d;
	private static IndexWriterConfig conf;
	private static final Properties PROPERTIES = new Properties();
	static  Analyzer analyzer = new AnsjAnalysis();

	static {

		try {
			InputStream is = DataSourceFactory.class.getResourceAsStream("/common.properties");
			PROPERTIES.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			//d = FSDirectory.open(Paths.get(PROPERTIES.getProperty("index_path")));
			d = FSDirectory.open(new File(PROPERTIES.getProperty("index_path")));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		conf=new IndexWriterConfig(Version.LATEST, analyzer);
	//	conf = new IndexWriterConfig(analyzer);
		conf.setOpenMode(OpenMode.CREATE_OR_APPEND);

	}

	public ProductBusinessView getPriceAndUrl(String id) {
		ProductBusinessView view=new ProductBusinessView();
		try {
			IndexSearcher searcher = LuceneUtils.getIndexSearcher(LuceneUtils.getIndexReader(d));
			Query q = new TermQuery(new Term("id", id));
			TopDocs tds = searcher.search(q, 1);
			if (tds != null && tds.scoreDocs.length == 1) {
				ScoreDoc doc = tds.scoreDocs[0];
				view.setPrice(Double.valueOf(searcher.doc(doc.doc).get("price")));
				view.setProductUrl(searcher.doc(doc.doc).get("productUrl"));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return view;
	}

	/**
	 * 
	 * @param keyWord
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	public List<CrawlProductView> searchPageByAfter(String keyWord, int pageIndex, int pageSize) {
		List<CrawlProductView> list = new ArrayList<CrawlProductView>();
		if (pageIndex <= 0) {
			pageIndex = 1;
		}
		if (pageSize <= 0) {
			pageSize = 4;
		}
		try {
			IndexSearcher searcher = LuceneUtils.getIndexSearcher(LuceneUtils.getIndexReader(d));
			Query q = new QueryParser("productName", new AnsjAnalysis()).parse(keyWord);
			ScoreDoc lastSd = null;
			try {
				lastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher);
			} catch (QueyException ee) {
				return list;
			} catch (Exception e) {
				e.printStackTrace();
			}
			TopDocs tds = searcher.searchAfter(lastSd, q, pageSize);
			for (ScoreDoc sd : tds.scoreDocs) {
				list.add(getViewFromDocument(searcher.doc(sd.doc)));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return list;
	}

	private CrawlProductView getViewFromDocument(Document document) {
		CrawlProductView crawlProductView = new CrawlProductView();
		crawlProductView.setId(document.get("id"));
		crawlProductView.setImageUrl(document.get("imageUrl"));
		crawlProductView.setProductName(document.get("productName"));
		crawlProductView.setBrandName(document.get("brandName"));
		if (document.get("webSource").trim().equals("京东")) {
			crawlProductView.setSource("京东");
			crawlProductView.setSourceType(SourceEnum.jd.getSource());
		} else if (document.get("webSource").trim().equals("天猫")) {
			crawlProductView.setSource("天猫");
			crawlProductView.setSourceType(SourceEnum.tmall.getSource());
		} else if (document.get("webSource").trim().equals("淘宝")) {
			crawlProductView.setSource("淘宝");
			crawlProductView.setSourceType(SourceEnum.taobao.getSource());
		} else {
			crawlProductView.setSource("其他");
			crawlProductView.setSourceType(SourceEnum.other.getSource());
		}
		JsonParser jsonParser = new JsonParser();
		Map<String, String> map = jsonParser.parse(document.get("params"));
		String onSaleDate = map.get("上架时间");
		if (StringUtil.isNotEmpty(onSaleDate)) {
			Date date = DateUtil.parseDate(onSaleDate, "yyyy-MM-dd");
			crawlProductView.setOnSaleDate(DateUtil.formatDateByFormat(date, "yyyy-MM-dd"));
		}
		crawlProductView.setProductNo(map.get("商品编号"));
		crawlProductView.setCo(map.get("商品产地"));
		return crawlProductView;
	}

	private ScoreDoc getLastScoreDoc(int pageIndex, int pageSize, Query query, IndexSearcher searcher)
			throws Exception {
		if (pageIndex == 1)
			return null;
		int num = pageSize * (pageIndex - 1);
		TopDocs tds = searcher.search(query, num);
		if (num > tds.totalHits) {
			throw new QueyException("数组下标超出限制");
		}
		return tds.scoreDocs[num - 1];
	}

}
